from django.db import transaction
from fdfs_client.client import Fdfs_client
from rest_framework import serializers
from rest_framework.response import Response
from apps.goods.models import SKU, SKUSpecification, GoodsCategory, SPUSpecification, SpecificationOption, SPU, Brand, \
    GoodsChannel, GoodsChannelGroup
from meiduo_mall import settings


class SpecSerializer(serializers.ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = ('id', 'value')


class SPUSpecSerializer(serializers.ModelSerializer):
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()
    options = SpecSerializer(many=True)

    class Meta:
        model = SPUSpecification
        fields = '__all__'


class SKUSpecSerializer(serializers.ModelSerializer):
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()

    class Meta:
        model = SKUSpecification
        fields = ('spec_id', 'option_id')


class SKUGoodsSerializer(serializers.ModelSerializer):
    category_id = serializers.IntegerField()
    category = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()
    spu = serializers.StringRelatedField(read_only=True)
    specs = SKUSpecSerializer(many=True)

    class Meta:
        model = SKU
        fields = '__all__'

    def create(self, validated_data):

        specs = validated_data['specs']

        with transaction.atomic():
            cur = transaction.savepoint()

            try:
                del validated_data['specs']
                sku = SKU.objects.create(**validated_data)
                for spec in specs:
                    SKUSpecification.objects.create(sku=sku, spec_id=spec['spec_id'], option_id=spec['option_id'])
            except:
                transaction.savepoint_rollback(cur)
                raise serializers.ValidationError('数据库错误')
            transaction.savepoint_commit(cur)
            return sku

    def update(self, instance, validated_data):
        specs = validated_data['specs']

        with transaction.atomic():
            cur = transaction.savepoint()

            try:
                del validated_data['specs']
                sku = SKU.objects.filter(id=instance.id).update(**validated_data)
                for spec in specs:
                    SKUSpecification.objects.filter(sku=instance, spec_id=spec['spec_id']).update(sku=sku, spec_id=spec[
                        'spec_id'], option_id=spec['option_id'])
            except:
                transaction.savepoint_rollback(cur)
                raise serializers.ValidationError('数据库错误')
            transaction.savepoint_commit(cur)
            sku = SKU.objects.get(id=instance.id)
            return sku


class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = ('id', 'name')


class SPUSerializer(serializers.ModelSerializer):
    brand = serializers.StringRelatedField(read_only=True)
    brand_id = serializers.IntegerField()
    category1_id = serializers.IntegerField()
    category2_id = serializers.IntegerField()
    category3_id = serializers.IntegerField()

    class Meta:
        model = SPU
        fields = (
            'id', 'name', 'brand', 'brand_id', 'category1_id', 'category2_id', 'category3_id', 'sales', 'comments',
            'desc_detail', 'desc_pack', 'desc_service')


class BrandSerializer(serializers.ModelSerializer):
    class Meta:
        model = Brand
        fields = ('name', 'id')


class SpecOptionSerializer(serializers.ModelSerializer):
    spec_id = serializers.IntegerField()
    spec = serializers.StringRelatedField()

    class Meta:
        model = SpecificationOption
        fields = ('id', 'value', 'spec', 'spec_id')


class GoodsChannelSerializer(serializers.ModelSerializer):
    group = serializers.StringRelatedField(read_only=True)
    group_id = serializers.IntegerField()
    category_id = serializers.IntegerField()
    category = serializers.StringRelatedField(read_only=True)

    class Meta:
        model = GoodsChannel
        fields = '__all__'
        # fields = ('id', 'category', 'category_id', 'group', 'group_id', 'sequence', 'url', 'create_time', 'update_time')


class GoodsChannelGroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsChannelGroup
        fields = ('id', 'name')


class BrandsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Brand
        fields = ('id', 'name', 'logo', 'first_letter')

    def create(self, validated_data):
        client = Fdfs_client(settings.FASTDFS_PATH)
        request = self.context['request']
        data = request.data.get('logo')
        res = client.upload_by_buffer(data.read())

        if res['Status'] != 'Upload successed.':
            return Response(status=403)

        logo_url = res['Remote file_id']

        name = request.data.get('name')
        first_letter = request.data.get('first_letter')
        img = Brand.objects.create(name=name, first_letter=first_letter, logo=logo_url)

        return img

    def update(self, instance, validated_data):
        client = Fdfs_client(settings.FASTDFS_PATH)
        request = self.context['request']
        data = request.data.get('logo')
        res = client.upload_by_buffer(data.read())

        if res['Status'] != 'Upload successed.':
            return Response(status=403)

        logo_url = res['Remote file_id']
        instance.name = request.data.get('name')
        instance.first_letter = request.data.get('first_letter')
        instance.logo = logo_url
        instance.save()

        return instance
